<style scoped>
</style>
<template>
    <div style="border: 1px dashed #e8eaec; padding: 0 10px">
        <el-form ref="formDynamic" :model="formDynamic" label-position="left">
            <div v-for="(item, index) in formDynamic.items" :key="attachIndex(item.field, index)">
                <el-divider orientation="left" dashed size="small">第 {{index + 1}} 行</el-divider>
                <form-create v-model="fApi[index]" :rule="rules[index]" :option="option" @table-field-on-change="onChange">
                </form-create>
                <el-button @click="handleRemove(index)" icon="md-remove" size="small"></el-button>
            </div>
            <el-divider dashed />
            <div style="margin-bottom:10px; ">
                <el-button type="success" @click="handleAdd" icon="md-add" size="small"></el-button>
            </div>
        </el-form>
    </div>
</template>
<script>
export default {
    name: 'tableDataForm',
    components: {
        formCreate: formCreate.$form()
    },
    props: {
        value: {
            type: Array,
            default () {
                return [];
            }
        },
        /* 行配置，设定了表格一行从左至右的列 */
        rowConfig: {
            type: Array,
            default () {
                return [];
            }
        }
    },
    data() {
        return {
            fApi: [],
            //表单生成规则
            //组件参数配置
            option: {
                submitBtn: false,
                resetBtn: false
            },
            formDynamic: {
                items: []
            },
            /* 因为form-create位于循环内，所以每个form-create需要有一个独立的rule */
            rules: []
        }
    },

    watch: {
        formDynamic: {
            handler(value) {
                //this.updateRule(value);
                this.emitValue();
            },
            deep: true
        }
    },
    created() {

    },
    mounted() {
        this.$nextTick(() => {
            /* 恢复数据 */
            var data = this.value;
            if (data !== undefined && data.length > 0) {
                this.formDynamic.items = [];
                /*如果配置中给予的值至少有一个，那么就可以不使用默认的值，要确保默认情况下会在页面上展现输入框*/
                let newIndex = 1;
                for (let i = 0; i < data.length; i++) {
                    if (Object.prototype.toString.call(data[i]) !== '[object Array]') {
                        data[i]._index = newIndex; /*重新排序*/
                        newIndex++;
                        data[i]._delMarker = 'n'; /*设置删除标记，供内部逻辑使用*/
                        this.formDynamic.items.push(data[i]);
                        this.updateRule(this.formDynamic);
                    }
                }
            }
        });
    },
    methods: {
        attachIndex(key, index) {
            return key + "-" + index;
        },
        /* 构造一个新的item */
        createDefaultItem(count) {
            let newItem = {};
            this.rowConfig.forEach((item) => {
                newItem[item.field] = '';
            });
            newItem._index = count + 1;
            newItem._delMarker = 'n';
            return newItem
        },
        /* 点击新增一条表格行数据 */
        handleAdd() {
            let count = this.formDynamic.items.length;
            let newItem = this.createDefaultItem(count);
            this.formDynamic.items.push(newItem);
            this.updateRule(this.formDynamic);
        },
        /*删除是基于更新_delMarker状态*/
        handleRemove(index) {
            /* 找到待删除的数据，然后设置标记为删除 */
            let modelItems = this.formDynamic.items;
            for (let i = 0; i < modelItems.length; i++) {
                let item = modelItems[i];
                if (index === i) {
                    item._delMarker = 'y';
                }
            }

            /* 重新构造数组 */
            let newItems = [];
            let availIndex = 1;
            for (let j = 0; j < modelItems.length; j++) {
                var item = modelItems[j];
                /* 如果数据没有被删除标记，则添加到新数组中 */
                if (item._delMarker === 'n') {
                    item._index = availIndex;
                    newItems.push(item);
                    availIndex++;
                }
            }
            /* 将新数组赋值给原数组 */
            this.formDynamic.items = newItems;
            this.updateRule(this.formDynamic);
        },
        /* 当内部组件输入值时就会触发这个方法，说明值已经发生变更了 */
        onChange() {
            let modelItems = this.formDynamic.items;
            let index = 0;
            this.fApi.forEach((item) => {
                //console.log("fApi" + index + ":" + JSON.stringify(item.formData()));
                /* eg. {stock: "123", name: "321"} */
                let rowData = item.formData();

                if (!modelItems[index]) {
                    /* 如果原值中没有包含这个index的数据，则意味着有新增数据 */
                    let count = modelItems.length;
                    let newItem = this.createDefaultItem(count);
                    modelItems.push(newItem);
                }

                for (let attr in rowData) {
                    /** 只复制我们需要的属性 */
                    modelItems[index][attr] = (rowData[attr]) ? rowData[attr] : "";
                }

                index++;
            });

            if (modelItems.length > this.fApi.length) {
                /* 如果原值中数据多于现有数据，则意味着有删减数据 */
                modelItems.splice(this.fApi.length, (modelItems.length - this.fApi.length));
            }


        },
        /* 更新组件的配置规则，目的是为了能恢复预设值 */
        updateRule(value) {
            /* 重置内部组件规则 */
            this.rules = [];
            /* items => [{stock: "123", name: "321"}, {stock: "123", name: "321"}, ...] */
            let items = value.items;
            items.forEach((rowCells) => {
                /**
                 * rowCells => {stock: "123", name: "321"}
                 */
                /* 
                 * 新建一行的默认配置，为一个数组,内部为当前行所涉及的组件的配置规则
                 * rowRuleArr => [{"emitPrefix":"tableField","field":"stock","type":"input","title":"股份","emit":["on-change"],"value":"","props":{},"validate":[]},{"emitPrefix":"tableField","field":"name","type":"input","title":"股东姓名","emit":["on-change"],"value":"","props":{},"validate":[]}]
                 */
                let rowRuleArr = JSON.parse(JSON.stringify(this.rowConfig));
                rowRuleArr.forEach((config) => {
                    /* 设置组件规则的value值，可以让组件显示这个值 */
                    config.value = rowCells[config.field];
                });
                /* 使用新的内部组件规则 */
                console.log("使用新的内部组件规则:" + JSON.stringify(this.rules));
                this.rules.push(rowRuleArr);
            });
        },
        /* 上报此组件的值，组件为一个单位，这个单位有值 */
        emitValue() {
            let valueCopy = JSON.parse(JSON.stringify(this.formDynamic.items));
            valueCopy.forEach((item) => {
                /* 清理无关属性 */
                delete item["_delMarker"];
                //delete item["_index"]; _index 其实后台可以用得上
            });
            this.$emit('input', valueCopy);
        }
    }
}
</script>